(function($) {
    
    function _setParams(page, params) {
        var _paramsStack = $(page).data("_paramsStack");
        if(!_paramsStack) {
            _paramsStack = [];
            $(page).data("_paramsStack", _paramsStack);
        }
        _paramsStack.push(params);
    }

    function _getParams(page) {
        var _paramsStack = $(page).data("_paramsStack");
        if(_paramsStack) {
            return _paramsStack.pop();
        }
        return null;
    }

    $.extend($, {
    	
        jump:function(routerId, params, silence) {
            var router = $.routers[routerId];
            if(router) {
                params = params ? params : {};
                var page = $("[data-page='" + routerId + "'");
                var hasNoPage = page.length == 0;
                //没有页面
                if(hasNoPage) {
                    var initPopup = null;
                    var initPanel = null;
                    function onMounted(vue, params) {
                        var popup = $(vue.$el).find(".popup");
                        var panel = $(vue.$el).find(".panel");
                        initPopup = popup;
                        initPanel = panel;
                        //初始化链接
                        $(vue.$el).initJump();
                        //挪到正确位置
                        popup.appendTo(document.body);
                        panel.insertAfter($(".panel-overlay"));
                        //保存参数
                        var currVue = $(document.body).data("_currentVue");
                        if(currVue) {
                            _setParams(currVue.$el, $(currVue.$el).data("_currentParams"));
                        }
                        _setParams(vue.$el, params);
                        //初始化，未显示之前
                        if(typeof(vue.init) == "function") {
                            vue.init(panel, popup);   
                        }

                        var onPageAfterAnimation = $.app.onPageAfterAnimation(routerId, function(pageData) {
                        	var params = _getParams(vue.$el);
                            $(vue.$el).data("_currentParams", params);
                            $(document.body).data("_currentVue", vue);
                            if(typeof(vue.resume) == "function") {
                                vue.resume(params);
                            }
                        });

                        var pageBeforeRemove = $.app.onPageBeforeRemove(routerId, function(pageData) {
                            onPageAfterAnimation.remove();
                            pageBeforeRemove.remove();
                            if(typeof(vue.destroy) == "function") {
                                vue.destroy();
                            }
                            popup.remove();
                            panel.remove();
                            vue.$destroy();
                        });
                        $.mainView.router.load({
                            pageName:routerId,
                            animatePages:!silence
                        });
                    }
                    page = $('<div data-page="' + routerId + '" class="page cached"></div>').appendTo($(".pages"));
                    page.load("tpl" + router.tpl, null, function(responseTxt, statusTxt, xhr) {
                        if(xhr.status == 200 || xhr.status == 0) {
                            var vueData = {};
                            if(router.controller) {
                                vueData.el = page.get(0);
                                seajs.use(router.controller, function(controller) {
                                    $.extend(vueData, controller());
                                    vueData.mounted = function() {
                                        onMounted(this, params);
                                    }
                                    vueData.updated = function() {
                                        if(initPopup) {
                                            initPopup.initJump();
                                        }
                                        if(initPanel) {
                                            initPanel.initJump();
                                        }
                                        $(this.$el).initJump();
                                    }
                                    new Vue(vueData);
                                });
                            } else {
                                vueData.$el = page.get(0);
                                $.extend(vueData, {
                                    init : function(panel, popup) {},
                                    resume : function(params) {},
                                    $destroy:function() {delete this;}
                                })
                                onMounted(vueData, params);
                            }
                        } else {
                            page.remove();
                        }
                    });
                    return;
                }
                //保存参数
                var currVue = $(document.body).data("_currentVue");
                if(currVue) {
                    _setParams(currVue.$el, $(currVue.$el).data("_currentParams"));
                }
                _setParams(page, params);
                //跳转
                $.mainView.router.load({
                    pageName:routerId,
                    animatePages:!silence
                });
            }
        }

    });
    var Refresh = function(el, callback) {
        var _this = this;

        var _refresh = $$(el).on("refresh", function() {
            _this.refresh();
        });

        this.refresh = function() {
            if(typeof(callback) == "function") {
                callback.call(this);
            }
        }

        this.finish = function() {
            $.app.pullToRefreshDone(_refresh);
        }

        if($(el).find(".pull-to-refresh-layer").length == 0) {
            var tpl = '<div class="pull-to-refresh-layer">' +
                            '<div class="preloader"></div>' +
                            '<div class="pull-to-refresh-arrow"></div>'+
                        '</div>';
            $(tpl).prependTo(el);
        }

    }

    var Paging = function(el, callback, size) {
        var pageSize = size ? size : 15;
        var page = 0;
        var loading = false;

        this.total = 0;
        this.more = true;

        this.reload = function() {
            page = 0;
            loading = false;
            this.total = 0;
            this.more = true;
            this.load();
        }

        this.load = function() {
            if(loading) {
                return;
            }
            if(!this.more) {
                return;
            }
            page ++;
            loading = true;
            $(el).find(".infinite-scroll-preloader").show();
            if(typeof(callback) == "function") {
                callback.call(this);
            }
        }

        this.push = function(targetItems, sourceItems, total) {
            this.total = total;
            for(var i=0; i<sourceItems.length; i++) {
                if(targetItems.length < MAX_ROWS) {
                    targetItems.push(sourceItems[i]);
                } else {
                    break;
                }
            }
            this.finish();
        }

        this.finish = function() {
            loading = false;
            if(this.more) {
                if(this.total > 0) {
                    this.more = page * pageSize < MAX_ROWS;
                    if(this.more) {
                        var pages = parseInt(this.total / pageSize);
                        pages = this.total % pageSize == 0 ? pages : pages + 1; 
                        this.more = page < pages;
                    }
                } else {
                    this.more = false;
                }
            }
            if(!this.more) {
                $(el).find(".infinite-scroll-preloader").hide();
            }
        }

        this.getPage = function() {
            return page;
        }

        this.getPageSize = function() {
            return pageSize;
        }
        if($(el).find(".infinite-scroll-preloader").length == 0) {
            var tpl = '<div class="infinite-scroll-preloader">' +
                            '<div class="preloader"></div>' +
                        '</div>';
            $(tpl).appendTo(el);
        }
    }

    var Pagings = function(el, callback, size, count) {

        var pagingCount = count ? count : 1;
        var pagings = [];

        for(var i=0; i<pagingCount; i++) {
            pagings.push(new Paging(el, callback, size));
        }

        this.index = 0;

        this.getPagingCount = function() {
            return pagingCount;
        }

        this.reload = function() {
            this.index = this.index > -1 && this.index < pagingCount ? this.index : 0;
            pagings[this.index].reload();
        }

        this.load = function() {
            this.index = this.index > -1 && this.index < pagingCount ? this.index : 0;
            pagings[this.index].load();
        }

    }

    $.extend($.fn, {

        initJump: function() {
            $(this).each(function(index, item) {
            	$(item).find("a:not(.jump)").off("click.nojump").on("click.nojump", function(e) {
                    e.preventDefault();
                });
                $(item).find(".jump").each(function(index, item) {
                    $(item).off("click.jump").on("click.jump", function() {
                        var routerId = this.href.substring(this.href.indexOf("#") + 1);
                        var params = null;
                        var paramsStr = $(this).attr("jump-params");
                        if(paramsStr) {
                            if(paramsStr.indexOf(":") > 0) {
                                params = eval("({" + paramsStr + "})");
                            } else {
                                params = paramsStr;
                            }
                        }
                        var silence = $(this).attr("jump-silence") == "true";
                        $.jump(routerId, params, silence);
                        return false;
                    });
                });
            });
        },
        refresh: function(callback) {
            var _this = this[0];
            var el = $(_this).hasClass("pull-to-refresh-content") ? _this : $(_this).find(".pull-to-refresh-content").get(0);
            var _refresh = $(el).data("_refresh");
            if(!_refresh) {
                _refresh = new Refresh(el, callback);
                $(el).data("_refresh", _refresh);
            }
            return _refresh;
        },
        infinite : function(callback, pageSize) {
            var _this = this[0];
            var el = $(_this).hasClass("infinite-scroll") ? _this : $(_this).find(".infinite-scroll").get(0);
            var _paging = $(el).data("_paging");
            if(!_paging) {
                _paging = new Paging(el, callback, pageSize);
                $$(el).on("infinite", function() {
                    _paging.load();
                });
                $(el).data("_paging", _paging);
            }
            return _paging;
        },
        infinites : function(callback, pageSize, count) {
            var _this = this[0];
            var el = $(_this).hasClass("infinite-scroll") ? _this : $(_this).find(".infinite-scroll").get(0);
            var _pagings = $(el).data("_paging");
            if(!_pagings) {
                _pagings = new Pagings(el, callback, pageSize, count);
                $$(el).on("infinite", function() {
                    _pagings.load();
                });
                $(el).data("_pagings", _pagings);
            }
            return _pagings;
        }

    });

    var BackKeyExit = function() {

        var canExitApp = false;

        this.onBackKeyClick = function() {
            if(canExitApp) {
                canExitApp = false;
                navigator.app.exitApp();
            } else {
                canExitApp = true;
                setTimeout(function() {
                    canExitApp = false;
                }, 5000);
                $.toast('再次按返回键，退出程序!', 5000);
            }
        };

    }

    
    function onDeviceReady() {
        $.jump("home");
    }

    var backKeyExit = new BackKeyExit();

    function onBackKeyDown() {
    	if(closeVisibleModel()) {
    		return;
    	}
        var link = window.location.href;
        var routerId = link.substring(link.indexOf("#") + 1);
        routerId = routerId.substring(routerId.indexOf("#") + 1);
        var homePages = ["home"];
        if(homePages.indexOf(routerId) > -1) {
            backKeyExit.onBackKeyClick();
        } else {
        	var vue = $(document.body).data("_currentVue");
        	if(vue) {
        		if(typeof(vue.onButtonBack) == "function") {
        			if(!vue.onButtonBack()) {
        				return;
        			} 
        		}
        	}
            $.back();
        }
    }

    function closeVisibleModel() {
    	//判断picker
		var pickers = $(".picker-modal:visible");
		if(pickers.length > 0) {
			$.app.closeModal($$(pickers.get(0)));
			return true;
		}
		//判断popup
		var popups = $(".popup:visible");
		if(popups.length > 0) {
			$.app.closeModal($$(popups.get(0)));
			return true;
		}
		//判断侧栏
		var panel = $(".panel:visible");
		if(panel.length > 0) {
			$.app.closePanel();
			return true;
		}
		//判断操作表
		var actions = $(".actions-modal:visible");
		if(actions.length > 0) {
			$.app.closeModal($$(actions.get(0)));
			return true;
		}
		//判断模态框
		if($(".modal-overlay-visible").length > 0) {
			return true;
		}
		return false;
	}
    

    //初始化
    document.addEventListener('deviceready', onDeviceReady, false);
    document.addEventListener("backbutton", onBackKeyDown, false);

})(jQuery ? jQuery : (Zepto ? Zepto : {}));


